package umacis.core;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import com.sun.lwuit.Form;
import com.sun.lwuit.util.Log;

import umacis.data.description.SystemViewDescription;
import umacis.data.elements.Action;
import umacis.data.elements.Binding;
import umacis.implementation.ActionHook;

public class ActionClassManager {

	private static final ActionClassManager INSTANCE = new ActionClassManager();
	String[] actionClassNames;
	Object[] actionClassObjects;
	Vector[] actionClassActionHooks;
//	Vector[] actionClassBindings;
	
	int index;
	private int instantiatedActionClassIndex = -1;
	private SystemViewDescription[] systemViewDescriptions;
	
	public static ActionClassManager getInstance() {
		return INSTANCE;
	}
	
	public void setCapacity(int size) {
		actionClassNames = new String[size];
		actionClassObjects = new Object[size];
		actionClassActionHooks = new Vector[size];
//		actionClassBindings = new Vector[size];
	}

	public void register(ActionHook actionHook) {
		actionClassActionHooks[instantiatedActionClassIndex].addElement(actionHook);
		actionHook.setActionClassIndex(instantiatedActionClassIndex);
		actionHook.setHookIndex(actionClassActionHooks[instantiatedActionClassIndex].size()-1);
	}
	
	public void register(Binding binding) {
		binding.getAction().setActionClassIndex(instantiatedActionClassIndex);
		if (instantiatedActionClassIndex == -1) Umacis.getInstance().add(binding);
		//else actionClassBindings[instantiatedActionClassIndex].addElement(binding);
	}
	
	public void delete(int actionClassIndex) {
		actionClassObjects[actionClassIndex] = null;
		actionClassActionHooks[actionClassIndex] = null;
	
	}

	public Object getActionClassInstance(int actionClassIndex) {
		if ( actionClassObjects[actionClassIndex] == null)
			try {
				actionClassActionHooks[instantiatedActionClassIndex = actionClassIndex] = new Vector();
				Object actionClassObject = actionClassObjects[actionClassIndex] = Class.forName(actionClassNames[actionClassIndex]).newInstance();
				if (instantiatedActionClassIndex<systemViewDescriptions.length) {
				//if (actionClassObject instanceof hasForm){
					Form form = ((hasForm)actionClassObject).getForm();
					form.putClientProperty("Description", systemViewDescriptions[instantiatedActionClassIndex]);					
				}
				instantiatedActionClassIndex = -1;
				
			} catch (InstantiationException e) {
				Log.p("Is this class an interface? Or abstract? " + actionClassNames[actionClassIndex], Log.ERROR);
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				Log.p("Class probably has no no-argument constructor, or is not public"+  actionClassNames[actionClassIndex], Log.ERROR);
				e.printStackTrace(); }
			catch (ClassNotFoundException e) {
			Log.p("Class not found "+ actionClassNames[actionClassIndex], Log.ERROR);
			e.printStackTrace();
			}
		return  actionClassObjects[actionClassIndex];
	}

	public void show(int systemViewDescriptionIndex) {
		 ((hasForm)getActionClassInstance(systemViewDescriptionIndex)).getForm().show();
		
	}
	
	public void execute(Action action) {
		if (action.getActionClassIndex() == -1) findActionClassIndex();
		getActionClassInstance(action.getActionClassIndex());
	}
	
	public void addClasses(SystemViewDescription[] systemViewDescriptions) {
		
		for (int i = 0; i<systemViewDescriptions.length; i++) {
			actionClassNames[index++] = systemViewDescriptions[i].getSystemViewClassName();
		}
		this.systemViewDescriptions = systemViewDescriptions;
		
	}
	
//	public void addClasses(String[] classNames) {
//		for (int i = 0; i<classNames.length; i++) {
//			actionClassNames[index++] = classNames[i];
//		}
//	}
	
	public void addClasses(Vector classNames) {
		Enumeration e = classNames.elements();
		while (e.hasMoreElements()) {
			actionClassNames[index++] = (String) e.nextElement();
		}	
	}

		

}
